﻿using NDF;
using NDF.Collections.Generic;
using NDF.Reflection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace System
{
    /// <summary>
    /// 扩展类型 <see cref="System.Type"/>，增加一些自定义方法。
    /// </summary>
    public static class TypeHelper
    {
        /// <summary>
        /// 获取指定对象的 <see cref="System.Type"/>。
        /// </summary>
        /// <param name="value">要获取类型的对象。</param>
        /// <returns>当前实例的准确运行时类型 <see cref="System.Type"/>。</returns>
        public static Type GetType(object value)
        {
            Guard.ArgumentNotNull(value, "value");
            return value.GetType();
        }


        /// <summary>
        /// 尝试获取具有指定名称的 System.Type，执行区分大小写的搜索。
        /// </summary>
        /// <param name="typeName">要获取的类型的程序集限定名称。 请参见 System.Type.AssemblyQualifiedName。 如果该类型位于当前正在执行的程序集中或者 Mscorlib.dll 中，则提供由命名空间限定的类型名称就足够了。</param>
        /// <param name="result">当此方法返回值时，如果找到该类型，便会返回获取到的类型；否则返回 null。</param>
        /// <returns>如果找到具有指定名称的类型，则返回 true，否则返回 false。</returns>
        public static bool TryGetType(string typeName, out Type result)
        {
            try
            {
                result = Type.GetType(typeName);
            }
            catch
            {
                result = null;
            }
            return result != null;
        }

        /// <summary>
        /// 尝试获取具有指定名称的 System.Type，同时执行大小写敏感的搜索，并指定是否要在没有找到该类型时引发异常。
        /// </summary>
        /// <param name="typeName">要获取的类型的程序集限定名称。 请参见 System.Type.AssemblyQualifiedName。 如果该类型位于当前正在执行的程序集中或者 Mscorlib.dll 中，则提供由命名空间限定的类型名称就足够了。</param>
        /// <param name="throwOnError">如果为 true，则在找不到该类型时引发异常；如果为 false，则返回 null。 指定 false 还会取消某些其他异常条件，但并不取消所有条件。</param>
        /// <param name="result">当此方法返回值时，如果找到该类型，便会返回获取到的类型；否则返回 null。</param>
        /// <returns>如果找到与查找条件相匹配的的类型，则返回 true，否则返回 false。</returns>
        public static bool TryGetType(string typeName, bool throwOnError, out Type result)
        {
            try
            {
                result = Type.GetType(typeName, throwOnError);
            }
            catch
            {
                result = null;
            }
            return result != null;
        }

        /// <summary>
        /// 尝试获取具有指定名称的 System.Type，指定是否执行区分大小写的搜索，以及在找不到类型时是否引发异常。
        /// </summary>
        /// <param name="typeName">要获取的类型的程序集限定名称。 请参见 System.Type.AssemblyQualifiedName。 如果该类型位于当前正在执行的程序集中或者 Mscorlib.dll 中，则提供由命名空间限定的类型名称就足够了。</param>
        /// <param name="throwOnError">true 则引发异常（如果找不到类型）；false 则返回null.Specifyingfalse，也抑制了其他一些异常情况，但不是所有异常。</param>
        /// <param name="ignoreCase">为 typeName 执行的搜索不区分大小写则为 true，为 typeName 执行的搜索区分大小写则为 false。</param>
        /// <param name="result">当此方法返回值时，如果找到该类型，便会返回获取到的类型；否则返回 null。</param>
        /// <returns>如果找到与查找条件相匹配的的类型，则返回 true，否则返回 false。</returns>
        public static bool TryGetType(string typeName, bool throwOnError, bool ignoreCase, out Type result)
        {
            try
            {
                result = Type.GetType(typeName, throwOnError, ignoreCase);
            }
            catch
            {
                result = null;
            }
            return result != null;
        }

        /// <summary>
        /// 尝试获取具有指定名称的类型，（可选）提供自定义方法以解析程序集和该类型。
        /// </summary>
        /// <param name="typeName">
        /// 要获取的类型的名称。 如果提供了 typeResolver 参数，则类型名称可以为 typeResolver 能够解析的任何字符串。 如果提供了
        ///     assemblyResolver 参数，或者使用了标准类型解析，则除非该类型位于当前正在执行的程序集或 Mscorlib.dll 中（在这种情况下足以提供其命名空间所限定的类型名称），否则
        ///     typeName 必须为程序集限定的名称（请参见 System.Type.AssemblyQualifiedName）。
        /// </param>
        /// <param name="assemblyResolver">
        /// 一个方法，它定位并返回 typeName 中指定的程序集。 以 System.Reflection.AssemblyName 对象形式传递给 assemblyResolver
        ///     的程序集名称。 如果 typeName 不包含程序集的名称，则不调用 assemblyResolver。 如果未提供 assemblyResolver，则执行标准程序集解析。
        ///     警告 不要通过未知的或不受信任的调用方传递方法。 此操作可能会导致恶意代码特权提升。 仅使用您提供或者熟悉的方法。
        /// </param>
        /// <param name="typeResolver">
        /// 一个方法，它在由 assemblyResolver 或标准程序集解析返回的程序集中定位并返回 typeName 所指定的类型。 如果未提供任何程序集，则
        ///     typeResolver 方法可以提供一个程序集。 该方法还采用一个参数以指定是否执行不区分大小写的搜索；false 传递给该参数。 警告 不要通过未知的或不受信任的调用方传递方法。
        /// </param>
        /// <param name="result">当此方法返回值时，如果找到该类型，便会返回获取到的类型；否则返回 null。</param>
        /// <returns>如果找到与查找条件相匹配的的类型，则返回 true，否则返回 false。</returns>
        public static bool TryGetType(string typeName, Func<AssemblyName, Assembly> assemblyResolver, Func<Assembly, string, bool, Type> typeResolver, out Type result)
        {
            try
            {
                result = Type.GetType(typeName, assemblyResolver, typeResolver);
            }
            catch
            {
                result = null;
            }
            return result != null;
        }

        /// <summary>
        /// 尝试获取具有指定名称的类型，指定在找不到该类型时是否引发异常，（可选）提供自定义方法以解析程序集和该类型。
        /// </summary>
        /// <param name="typeName">
        /// 要获取的类型的名称。 如果提供了 typeResolver 参数，则类型名称可以为 typeResolver 能够解析的任何字符串。 如果提供了
        ///     assemblyResolver 参数，或者使用了标准类型解析，则除非该类型位于当前正在执行的程序集或 Mscorlib.dll 中（在这种情况下足以提供其命名空间所限定的类型名称），否则
        ///     typeName 必须为程序集限定的名称（请参见 System.Type.AssemblyQualifiedName）。
        /// </param>
        /// <param name="assemblyResolver"></param>
        /// <param name="typeResolver">
        /// 一个方法，它定位并返回 typeName 中指定的程序集。 以 System.Reflection.AssemblyName 对象形式传递给 assemblyResolver
        ///     的程序集名称。 如果 typeName 不包含程序集的名称，则不调用 assemblyResolver。 如果未提供 assemblyResolver，则执行标准程序集解析。
        ///     警告 不要通过未知的或不受信任的调用方传递方法。 此操作可能会导致恶意代码特权提升。 仅使用您提供或者熟悉的方法。
        /// </param>
        /// <param name="throwOnError">
        /// 一个方法，它在由 assemblyResolver 或标准程序集解析返回的程序集中定位并返回 typeName 所指定的类型。 如果未提供任何程序集，则该方法可以提供一个程序集。
        ///     该方法还采用一个参数以指定是否执行不区分大小写的搜索；false 传递给该参数。 警告 不要通过未知的或不受信任的调用方传递方法。
        /// </param>
        /// <param name="result">当此方法返回值时，如果找到该类型，便会返回获取到的类型；否则返回 null。</param>
        /// <returns>如果找到与查找条件相匹配的的类型，则返回 true，否则返回 false。</returns>
        public static bool TryGetType(string typeName, Func<AssemblyName, Assembly> assemblyResolver, Func<Assembly, string, bool, Type> typeResolver, bool throwOnError, out Type result)
        {
            try
            {
                result = Type.GetType(typeName, assemblyResolver, typeResolver, throwOnError);
            }
            catch
            {
                result = null;
            }
            return result != null;
        }

        /// <summary>
        /// 尝试获取具有指定名称的类型，指定是否执行区分大小写的搜索，在找不到类型时是否引发异常，（可选）提供自定义方法以解析程序集和该类型。
        /// </summary>
        /// <param name="typeName">
        /// 要获取的类型的名称。 如果提供了 typeResolver 参数，则类型名称可以为 typeResolver 能够解析的任何字符串。 如果提供了
        ///     assemblyResolver 参数，或者使用了标准类型解析，则除非该类型位于当前正在执行的程序集或 Mscorlib.dll 中（在这种情况下足以提供其命名空间所限定的类型名称），否则
        ///     typeName 必须为程序集限定的名称（请参见 System.Type.AssemblyQualifiedName）。
        /// </param>
        /// <param name="assemblyResolver">
        /// 一个方法，它定位并返回 typeName 中指定的程序集。 以 System.Reflection.AssemblyName 对象形式传递给 assemblyResolver
        ///     的程序集名称。 如果 typeName 不包含程序集的名称，则不调用 assemblyResolver。 如果未提供 assemblyResolver，则执行标准程序集解析。
        ///     警告 不要通过未知的或不受信任的调用方传递方法。 此操作可能会导致恶意代码特权提升。 仅使用您提供或者熟悉的方法。
        /// </param>
        /// <param name="typeResolver">
        /// 一个方法，它在由 assemblyResolver 或标准程序集解析返回的程序集中定位并返回 typeName 所指定的类型。 如果未提供任何程序集，则该方法可以提供一个程序集。
        ///     该方法还采用一个参数以指定是否执行不区分大小写的搜索；ignoreCase 的值传递给该参数。 警告 不要通过未知的或不受信任的调用方传递方法。
        /// </param>
        /// <param name="throwOnError">如果为 true，则在找不到该类型时引发异常；如果为 false，则返回 null。 指定 false 还会取消某些其他异常条件，但并不取消所有条件。</param>
        /// <param name="ignoreCase">为 typeName 执行的搜索不区分大小写则为 true，为 typeName 执行的搜索区分大小写则为 false。</param>
        /// <param name="result">当此方法返回值时，如果找到该类型，便会返回获取到的类型；否则返回 null。</param>
        /// <returns>如果找到与查找条件相匹配的的类型，则返回 true，否则返回 false。</returns>
        public static bool TryGetType(string typeName, Func<AssemblyName, Assembly> assemblyResolver, Func<Assembly, string, bool, Type> typeResolver, bool throwOnError, bool ignoreCase, out Type result)
        {
            try
            {
                result = Type.GetType(typeName, assemblyResolver, typeResolver, throwOnError, ignoreCase);
            }
            catch
            {
                result = null;
            }
            return result != null;
        }



        /// <summary>
        /// 判断当前 <see cref="System.Type"/> 指示的类型是否继承于（或等价于）某个 <see cref="System.Type"/> 类型。
        /// </summary>
        /// <param name="type">当前 <see cref="System.Type"/> 对象。</param>
        /// <param name="c">用于比较的 <see cref="System.Type"/> 类型对象。</param>
        /// <returns>如果当前类型等价或继承与指定的类型，则返回 true，否则返回 false。</returns>
        public static bool IsInhertOf(this System.Type type, System.Type c)
        {
            return type == c || type.IsSubclassOf(c);
        }

        /// <summary>
        /// 判断当前 <see cref="System.Type"/> 指示的类型是否实现或(等价于)某个 <see cref="System.Type"/> 指示的接口。
        /// </summary>
        /// <param name="type">当前 <see cref="System.Type"/> 对象。</param>
        /// <param name="c">用于比较的 <see cref="System.Type"/> 类型对象，表示一个接口类型。</param>
        /// <returns>如果当前类型等价或继承与指定的接口类型，则返回 true，否则返回 false。</returns>
        public static bool IsImplementOf(this System.Type type, System.Type c)
        {
            return type == c || type.GetInterfaces().Contains(c);
        }

        /// <summary>
        /// 判断当前 <see cref="System.Type"/> 指示的类型是否实现、继承等价于某个 <see cref="System.Type"/> 指示的类型或接口。
        /// </summary>
        /// <param name="type">当前 <see cref="System.Type"/> 对象。</param>
        /// <param name="c">用于比较的 <see cref="System.Type"/> 类型对象。</param>
        /// <returns>如果当前类型实现、继承等价于指定的类型或接口，则返回 true，否则返回 false。</returns>
        public static bool IsInhertOrImplementOf(this System.Type type, System.Type c)
        {
            return type.IsInhertOf(c) || type.IsImplementOf(c);
        }




        /// <summary>
        /// 获取当前类型的所有子类或接口实现类。
        /// </summary>
        /// <param name="thisType">当前 <see cref="System.Type"/> 对象。</param>
        /// <returns>当前类型的所有子类或接口实现类。</returns>
        public static Type[] GetSubClass(this Type thisType)
        {
            return GetSubClass(thisType, AssemblyDomain.AppDomain);
        }

        /// <summary>
        /// 获取当前类型在指定应用程序集范围的所有子类或接口实现类。
        /// </summary>
        /// <param name="thisType">当前 <see cref="System.Type"/> 对象。</param>
        /// <param name="assemblyDomain">指定的应用程序集范围</param>
        /// <returns>当前类型在指定应用程序集范围的所有子类或接口实现类。</returns>
        public static Type[] GetSubClass(this Type thisType, AssemblyDomain assemblyDomain)
        {
            return GetTypes(assemblyDomain).Where(t => t != thisType && t.IsInhertOrImplementOf(thisType)).ToArray();
        }


        /// <summary>
        /// 获取当前类型在所有已经加载的应用程序集中的所有父类。
        /// </summary>
        /// <param name="thisType">当前 <see cref="System.Type"/> 对象。</param>
        /// <returns>
        /// 当前类型在所有已经加载的应用程序集中的所有父类 <see cref="System.Type"/> 所构成的一个数组；
        /// 如果当前类型没有任何父类(当前类型为 <see cref="System.Object"/>)，则返回一个长度为 0 的空数组。
        /// </returns>
        public static Type[] GetParentClass(this Type thisType)
        {
            List<Type> list = new List<Type>();
            Type type = thisType;
            while (type.BaseType != null)
            {
                list.Add(type.BaseType);
                type = type.BaseType;
            }
            return list.ToArray();
        }



        /// <summary>
        /// 获取已加载到此应用程序域执行上下文所有程序集中定义的所有类型<see cref="System.Type"/>集合所构成的一个数组。
        /// 该方法等同于 <see cref="NDF.AssemblyHelper.GetTypes()"/>。
        /// </summary>
        /// <returns>已加载到此应用程序域执行上下文所有程序集中定义的所有类型<see cref="System.Type"/>集合所构成的一个数组。</returns>
        public static Type[] GetTypes()
        {
            return AssemblyHelper.GetTypes();
        }

        /// <summary>
        /// 获取已加载到指定应用程序域作用范围内执行上下文所有程序集中定义的所有类型<see cref="System.Type"/>集合所构成的一个数组。
        /// 该方法等同于 <see cref="NDF.AssemblyHelper.GetTypes(AssemblyDomain)"/>。
        /// </summary>
        /// <param name="domain">指定的应用程序域作用范围。</param>
        /// <returns>已加载到指定应用程序域作用范围内执行上下文所有程序集中定义的所有类型<see cref="System.Type"/>集合所构成的一个数组。</returns>
        public static Type[] GetTypes(AssemblyDomain domain)
        {
            return AssemblyHelper.GetTypes(domain);
        }

        /// <summary>
        /// 获取已加载到此应用程序域执行上下文所有程序集中定义的所有公共类型<see cref="System.Type"/>集合(这些公共类型在程序集外可见)所构成的一个数组。
        /// 该方法等同于 <see cref="NDF.AssemblyHelper.GetPublicTypes()"/>。
        /// </summary>
        /// <returns>已加载到此应用程序域执行上下文所有程序集中定义的所有公共类型<see cref="System.Type"/>集合(这些公共类型在程序集外可见)所构成的一个数组。</returns>
        public static Type[] GetPublicTypes()
        {
            return AssemblyHelper.GetPublicTypes();
        }

        /// <summary>
        /// 获取已加载到指定应用程序域作用范围内执行上下文所有程序集中定义的所有公共类型<see cref="System.Type"/>集合(这些公共类型在程序集外可见)所构成的一个数组。
        /// 该方法等同于 <see cref="NDF.AssemblyHelper.GetPublicTypes(AssemblyDomain)"/>。
        /// </summary>
        /// <param name="domain">指定的应用程序域作用范围。</param>
        /// <returns>已加载到指定应用程序域作用范围内执行上下文所有程序集中定义的所有公共类型<see cref="System.Type"/>集合(这些公共类型在程序集外可见)所构成的一个数组。</returns>
        public static Type[] GetPublicTypes(AssemblyDomain domain)
        {
            return AssemblyHelper.GetPublicTypes(domain);
        }



        /// <summary>
        /// 获取已加载到此应用程序执行上下文所有程序集中指定命名空间中的所有类型<see cref="System.Type"/>集合所构成的一个数组。
        /// </summary>
        /// <param name="nameSpace">指定的命名空间</param>
        /// <returns>已加载到此应用程序执行上下文所有程序集中指定命名空间中的所有类型<see cref="System.Type"/>集合所构成的一个数组。</returns>
        public static Type[] GetTypes(string nameSpace)
        {
            return GetTypes(nameSpace, AssemblyDomain.AppDomain);
        }

        /// <summary>
        /// 获取已加载到指定应用程序域作用范围内执行上下文所有程序集中指定命名空间中的所有类型<see cref="System.Type"/>集合所构成的一个数组。
        /// </summary>
        /// <param name="nameSpace">指定的命名空间</param>
        /// <param name="domain">指定的应用程序域作用范围</param>
        /// <returns>已加载到指定应用程序域作用范围内执行上下文所有程序集中指定命名空间中的所有类型<see cref="System.Type"/>集合所构成的一个数组。</returns>
        public static Type[] GetTypes(string nameSpace, AssemblyDomain domain)
        {
            return GetTypes(domain).Where(t => t.Namespace.Equals(nameSpace, StringComparison.CurrentCulture)).ToArray();
        }


        /// <summary>
        /// 获取已加载到此应用程序执行上下文所有程序集中指定命名空间中的所有公共类型<see cref="System.Type"/>集合(这些公共类型在程序集外可见)所构成的一个数组。
        /// </summary>
        /// <param name="nameSpace">指定的命名空间</param>
        /// <returns>已加载到此应用程序执行上下文所有程序集中指定命名空间中的所有公共类型<see cref="System.Type"/>集合(这些公共类型在程序集外可见)所构成的一个数组。</returns>
        public static Type[] GetPublicTypes(string nameSpace)
        {
            return GetPublicTypes(nameSpace, AssemblyDomain.AppDomain);
        }

        /// <summary>
        /// 获取已加载到指定应用程序域作用范围内执行上下文所有程序集中指定命名空间中的所有公共类型<see cref="System.Type"/>集合(这些公共类型在程序集外可见)所构成的一个数组。
        /// </summary>
        /// <param name="nameSpace">指定的命名空间</param>
        /// <param name="domain">指定的应用程序域作用范围</param>
        /// <returns>已加载到指定应用程序域作用范围内执行上下文所有程序集中指定命名空间中的所有公共类型<see cref="System.Type"/>集合(这些公共类型在程序集外可见)所构成的一个数组。</returns>
        public static Type[] GetPublicTypes(string nameSpace, AssemblyDomain domain)
        {
            return GetPublicTypes(domain).Where(t => t.Namespace.Equals(nameSpace, StringComparison.CurrentCulture)).ToArray();
        }




        /// <summary>
        /// 获取当前 <see cref="System.Type"/> 定义的所有属性，包括其所有内部成员和继承的属性。
        /// </summary>
        /// <param name="type">当前 <see cref="System.Type"/> 对象。</param>
        /// <returns>当前 <see cref="System.Type"/> 定义的所有 <see cref="System.Reflection.PropertyInfo"/> 所构成的一个数组（如果找到的话）；否则为空数组。</returns>
        public static PropertyInfo[] GetAllProperties(this Type type)
        {
            return type.GetProperties(BindingFlagsAll);
        }

        /// <summary>
        /// 获取当前 <see cref="System.Type"/> 定义的所有指定名称的属性，包括其所有内部成员和继承的属性。
        /// </summary>
        /// <param name="type">当前 <see cref="System.Type"/> 对象。</param>
        /// <param name="name">指定的属性名称。</param>
        /// <returns>当前 <see cref="System.Type"/> 定义的所有指定名称的 <see cref="System.Reflection.PropertyInfo"/> 所构成的一个数组（如果找到的话）；否则为空数组。</returns>
        public static PropertyInfo[] GetAllProperties(this Type type, string name)
        {
            Guard.ArgumentNotNullOrWhiteSpace(name, "name");
            return type.GetProperties(BindingFlagsAll).Where(field => field.Name == name).ToArray();
        }


        /// <summary>
        /// 获取当前 <see cref="System.Type"/> 定义的所有方法，包括其所有内部成员和继承的方法。
        /// </summary>
        /// <param name="type">当前 <see cref="System.Type"/> 对象。</param>
        /// <returns>当前 <see cref="System.Type"/> 定义的所有方法 <see cref="System.Reflection.MethodInfo"/> 所构成的一个数组（如果找到的话）；否则为空数组。</returns>
        public static MethodInfo[] GetAllMethods(this Type type)
        {
            return type.GetMethods(BindingFlagsAll);
        }

        /// <summary>
        /// 获取当前 <see cref="System.Type"/> 定义的所有指定名称的方法，包括其所有内部成员和继承的方法。
        /// </summary>
        /// <param name="type">当前 <see cref="System.Type"/> 对象。</param>
        /// <param name="name">指定的方法名称。</param>
        /// <returns>当前 <see cref="System.Type"/> 定义的所有指定名称的方法 <see cref="System.Reflection.MethodInfo"/> 所构成的一个数组（如果找到的话）；否则为空数组。</returns>
        public static MethodInfo[] GetAllMethods(this Type type, string name)
        {
            Guard.ArgumentNotNullOrWhiteSpace(name, "name");
            return type.GetMethods(BindingFlagsAll).Where(field => field.Name == name).ToArray();
        }

        /// <summary>
        /// 获取当前 <see cref="System.Type"/> 定义的所有指定名称和参数列表的方法，包括其所有内部成员和继承的方法。
        /// </summary>
        /// <param name="type">当前 <see cref="System.Type"/> 对象。</param>
        /// <param name="name">指定的方法名称。</param>
        /// <param name="parameterTypes">指定的方法参数列表及类型。</param>
        /// <returns>当前 <see cref="System.Type"/> 定义的所有指定名称和参数列表的方法 <see cref="System.Reflection.MethodInfo"/> 所构成的一个数组（如果找到的话）；否则为空数组。</returns>
        public static MethodInfo[] GetAllMethods(this Type type, string name, params Type[] parameterTypes)
        {
            var methods = GetAllMethods(type, name);
            return (parameterTypes == null || parameterTypes.Length == 0) ? methods : methods.Where(method =>
            {
                var parameters = method.GetParameters();
                return parameterTypes.Length == parameters.Length && parameters.All((p, i) => p.ParameterType == parameterTypes[i]);
            }).ToArray();
        }


        /// <summary>
        /// 获取当前 <see cref="System.Type"/> 定义的所有事件，包括其所有内部成员和继承的事件。
        /// </summary>
        /// <param name="type">当前 <see cref="System.Type"/> 对象。</param>
        /// <returns>当前 <see cref="System.Type"/> 定义的所有事件 <see cref="System.Reflection.EventInfo"/> 所构成的一个数组（如果找到的话）；否则为空数组。</returns>
        public static EventInfo[] GetAllEvents(this Type type)
        {
            return type.GetEvents(BindingFlagsAll);
        }

        /// <summary>
        /// 获取当前 <see cref="System.Type"/> 定义的所有指定名称事件，包括其所有内部成员和继承的事件。
        /// </summary>
        /// <param name="type">当前 <see cref="System.Type"/> 对象。</param>
        /// <param name="name">指定的事件名称。</param>
        /// <returns>当前 <see cref="System.Type"/> 定义的所有指定名称事件 <see cref="System.Reflection.EventInfo"/> 所构成的一个数组（如果找到的话）；否则为空数组。</returns>
        public static EventInfo[] GetAllEvents(this Type type, string name)
        {
            Guard.ArgumentNotNullOrWhiteSpace(name, "name");
            return type.GetEvents(BindingFlagsAll).Where(field => field.Name == name).ToArray();
        }


        /// <summary>
        /// 获取当前 <see cref="System.Type"/> 定义的所有字段，包括其所有内部成员和继承的字段。
        /// </summary>
        /// <param name="type">当前 <see cref="System.Type"/> 对象。</param>
        /// <returns>当前 <see cref="System.Type"/> 定义的所有字段 <see cref="System.Reflection.FieldInfo"/> 所构成的一个数组（如果找到的话）；否则为空数组。</returns>
        public static FieldInfo[] GetAllFields(this Type type)
        {
            return type.GetFields(BindingFlagsAll);
        }

        /// <summary>
        /// 获取当前 <see cref="System.Type"/> 定义的所有指定名称字段，包括其所有内部成员和继承的字段。
        /// </summary>
        /// <param name="type">当前 <see cref="System.Type"/> 对象。</param>
        /// <param name="name">指定的字段名称。</param>
        /// <returns>当前 <see cref="System.Type"/> 定义的所有指定名称字段 <see cref="System.Reflection.FieldInfo"/> 所构成的一个数组（如果找到的话）；否则为空数组。</returns>
        public static FieldInfo[] GetAllFields(this Type type, string name)
        {
            Guard.ArgumentNotNullOrWhiteSpace(name, "name");
            return type.GetFields(BindingFlagsAll).Where(field => field.Name == name).ToArray();
        }




        /// <summary>
        /// 获取当前 <see cref="System.Type"/> 定义的所有指定名称成员，包括其所有内部成员和继承的成员。
        /// </summary>
        /// <param name="type">表示待查找成员的 System.Type 对象。</param>
        /// <param name="name">指定的 MemberInfo 名称。</param>
        /// <returns>返回 System.Type 对象中符合过滤条件的所有 MemberInfo 成员对象。</returns>
        public static MemberInfo[] GetAllMembers(this Type type, string name)
        {
            return type.GetMember(name, BindingFlagsAll);
        }

        /// <summary>
        /// 获取当前 <see cref="System.Type"/> 定义的指定类型的所有成员，包括其所有内部成员和继承的成员。
        /// </summary>
        /// <param name="type">表示待查找成员的 System.Type 对象。</param>
        /// <param name="memberType">指定的 MemberTypes 成员类型；如果该参数值为 MemberTypes.All，则不按成员类型过滤返回列表。</param>
        /// <returns>返回 System.Type 对象中符合过滤条件的所有 MemberInfo 成员对象。</returns>
        public static MemberInfo[] GetAllMembers(this Type type, MemberTypes memberType)
        {
            return type.GetMembers(BindingFlagsAll).Where(t => memberType.HasFlag(t.MemberType)).ToArray();
        }

        /// <summary>
        /// 获取当前 <see cref="System.Type"/> 定义的指定名称和类型的所有成员，包括其所有内部成员和继承的成员。
        /// </summary>
        /// <param name="type">表示待查找成员的 System.Type 对象。</param>
        /// <param name="name">指定的 MemberInfo 名称。</param>
        /// <param name="memberType">指定的 MemberTypes 成员类型；如果该参数值为 MemberTypes.All，则不按成员类型过滤返回列表。</param>
        /// <returns>一个表示具有指定名称的公共成员的 <see cref="System.Reflection.MemberInfo"/> 对象数组（如果找到的话）；否则为空数组。</returns>
        public static MemberInfo[] GetAllMembers(this Type type, string name, MemberTypes memberType)
        {
            return type.GetMember(name, memberType, BindingFlagsAll);
        }

        /// <summary>
        /// 获取当前 <see cref="System.Type"/> 定义的所有成员，包括其所有内部成员和继承的成员。
        /// </summary>
        /// <param name="type">表示待查找成员的 System.Type 对象。</param>
        /// <returns>返回指定 System.Type 对象的所有成员(包括其所有内部成员和继承的成员)。</returns>
        public static MemberInfo[] GetAllMembers(this Type type)
        {
            return type.GetMembers(BindingFlagsAll);
        }





        /// <summary>
        /// 指定控制绑定和由反射执行的成员和类型搜索方法标志的所有搜索范围。
        /// 包含 公共成员(Public)、非公共成员(NonPublic)、实例成员(Instance) 和 静态成员(Static)。
        /// </summary>
        public static readonly BindingFlags BindingFlagsAll = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;

    }
}
